package cn.edu.xmu.javaee.productdemomybatis.util;

import cn.edu.xmu.javaee.core.model.IdNameTypeVo;
import cn.edu.xmu.javaee.productdemomybatis.mapper.generator.po.OnSalePo;
import cn.edu.xmu.javaee.productdemomybatis.mapper.generator.po.ProductPo;
import cn.edu.xmu.javaee.productdemomybatis.service.vo.ProductVo;
import cn.edu.xmu.javaee.productdemomybatis.service.vo.OnSaleVo;
import cn.edu.xmu.javaee.productdemomybatis.service.vo.CustomerProductVo;
import cn.edu.xmu.javaee.productdemomybatis.controller.dto.ProductDto;
import cn.edu.xmu.javaee.productdemomybatis.dao.bo.OnSale;
import cn.edu.xmu.javaee.productdemomybatis.dao.bo.Product;
import cn.edu.xmu.javaee.productdemomybatis.mapper.manual.po.ProductAllPo;

import java.util.Objects;
import java.util.stream.Collectors;

public class CloneFactory {

    public static OnSale copy(OnSale target, OnSalePo source) {
        target = OnSale.builder().id(source.getId()).beginTime(source.getBeginTime()).endTime(source.getEndTime()).price(source.getPrice()).quantity(source.getQuantity())
                .maxQuantity(source.getMaxQuantity()).creator(source.getCreator()).modifier(source.getModifier())
                .gmtCreate(source.getGmtCreate()).gmtModified(source.getGmtModified()).build();
        return target;
    }

    public static Product copy(Product target, ProductPo source){
        target = Product.builder().id(source.getId()).name(source.getName()).barcode(source.getBarcode()).originalPrice(source.getOriginalPrice()).originPlace(source.getOriginPlace())
                .weight(source.getWeight()).unit(source.getUnit()).commissionRatio(source.getCommissionRatio()).freeThreshold(source.getFreeThreshold())
                .creator(source.getCreator()).modifier(source.getModifier()).gmtCreate(source.getGmtCreate()).gmtModified(source.getGmtModified()).shopId(source.getShopId()).build();
        return target;
    }

    public static Product copy(Product target, ProductAllPo source){
        target = Product.builder().id(source.getId()).name(source.getName()).barcode(source.getBarcode()).originalPrice(source.getOriginalPrice()).originPlace(source.getOriginPlace())
                .weight(source.getWeight()).unit(source.getUnit()).commissionRatio(source.getCommissionRatio()).freeThreshold(source.getFreeThreshold())
                .creator(source.getCreator()).modifier(source.getModifier()).gmtCreate(source.getGmtCreate()).gmtModified(source.getGmtModified()).shopId(source.getShopId()).build();
        Integer id = target.getId();
        if (Objects.nonNull(source.getOnSaleList())) {
            target.setOnSaleList(source.getOnSaleList().stream().map(o -> CloneFactory.copy(new OnSale(), o)).collect(Collectors.toList()));
        }
        if (Objects.nonNull(source.getOtherProduct())) {
            target.setOtherProduct(source.getOtherProduct().stream().filter(o -> !(o.getId().equals(id))).map(o -> CloneFactory.copy(new Product(), o)).collect(Collectors.toList()));
        }
        return target;
    }

    public static ProductPo copy(ProductPo target, Product source){
        target.setId(source.getId());
        target.setShopId(source.getShopId());
        target.setName(source.getName());
        target.setBarcode(source.getBarcode());
        target.setOriginalPrice(source.getOriginalPrice());
        target.setUnit(source.getUnit());
        target.setCommissionRatio(source.getCommissionRatio());
        target.setWeight(source.getWeight());
        target.setFreeThreshold(source.getFreeThreshold());
        target.setStatus(source.getStatus());
        target.setOriginPlace(source.getOriginPlace());
        target.setCreator(source.getCreator());
        target.setModifier(source.getModifier());
        target.setGmtModified(source.getGmtModified());
        target.setGmtCreate(source.getGmtCreate());
        return  target;
    }

    public static CustomerProductVo copy(CustomerProductVo target, Product source){
            target = CustomerProductVo.builder().id(source.getId()).name(source.getName()).unit(source.getUnit()).originalPrice(source.getOriginalPrice()).barcode(source.getBarcode())
            .weight(source.getWeight()).originPlace(source.getOriginPlace()).shopId(source.getShopId()).build();
        if (Objects.nonNull(source.getOnSaleList())){
            OnSale onSale = source.getOnSaleList().get(0);
            target.setPrice(onSale.getPrice());
            target.setQuantity(onSale.getQuantity());
            target.setMaxQuantity(onSale.getMaxQuantity());
            target.setSkuSn(onSale.getSkuSn());
        }

        if (Objects.nonNull(source.getOtherProduct())) {
            target.setOtherProduct(source.getOtherProduct().stream().map(o -> CloneFactory.copy(new CustomerProductVo(), o)).collect(Collectors.toList()));
        }
        return target;
    }

    public static ProductVo copy(ProductVo target, Product source){
        target = ProductVo.builder().id(source.getId()).name(source.getName()).unit(source.getUnit()).originalPrice(source.getOriginalPrice()).barcode(source.getBarcode())
                .weight(source.getWeight()).originPlace(source.getOriginPlace()).creator(source.getCreator()).modifier(source.getModifier())
                .gmtCreate(source.getGmtCreate()).gmtModified(source.getGmtModified()).shopId(source.getShopId()).build();
        if (Objects.nonNull(source.getOnSaleList())) {
            target.setOnsaleList(source.getOnSaleList().stream().map(o -> CloneFactory.copy(new OnSaleVo(), o)).collect(Collectors.toList()));
        }
        if (Objects.nonNull(source.getOtherProduct())) {
            target.setOtherProduct(source.getOtherProduct().stream().map(o -> CloneFactory.copy(new CustomerProductVo(), o)).collect(Collectors.toList()));
        }
        return target;
    }

    public static OnSaleVo copy(OnSaleVo target, OnSale source){
        target = OnSaleVo.builder().id(source.getId()).beginTime(source.getBeginTime()).endTime(source.getEndTime()).price(source.getPrice()).quantity(source.getQuantity()).maxQuantity(source.getMaxQuantity()).skuSn(source.getSkuSn())
                .creator(source.getCreator()).modifier(source.getModifier()).gmtModified(source.getGmtModified()).gmtCreate(source.getGmtCreate()).build();
        return target;
    }

    public static Product copy(Product target, ProductDto source){
        target=Product.builder().name(source.getName()).barcode(source.getBarcode()).unit(source.getUnit()).originalPrice(source.getOriginalPrice()).originPlace(source.getOriginPlace()).weight(source.getWeight()).build();
        return target;
    }
}
